#include "fig_bonefile_cache.h"
#include "fig_constants.h"
#include "script/scripthelper.h"
#include "fighter.h"

#include "graphics/graphics_util.h"
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros

using namespace script;

FIGBoneFileCache::FIGBoneFileCache()						
{

}




FIGBoneFileCache&	FIGBoneFileCache::Instance()
{
	static FIGBoneFileCache	Inst;
	return Inst;
}


void		FIGBoneFileCache::ReadAndCacheFiles(FileLoadedCB pCB, void* pData)
{
	
	std::vector<std::string>		m_Files;
	std::string FileName;
	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	{
		if (!ScriptHelper::DoFile(*pScript, "transform/bonefilelist.lua"))
		{
			LuaPlus::LuaState::Destroy( pScript );
			return;
		} 	
		
		LuaPlus::LuaObject Table = pScript->GetGlobal("BoneFiles");
		for(int i =0; i <Table.GetTableCount(); i++)
		{
			LuaPlus::LuaObject Obj = Table.GetByIndex(i+1);

			FileName = ScriptHelper::GetTableString(Obj,"Name"); 
			m_Files.push_back(FileName);
		}
	}
	LuaPlus::LuaState::Destroy( pScript );
	if(pData)
		pCB(pData);


	for(int i =0; i < (int)m_Files.size(); i++)
	{
		ReadSingleFile(m_Files[i]);
		if(pData)
			pCB(pData);
	} 
}


void		FIGBoneFileCache::ReadSingleFile(const std::string& File)
{
	

	BoneFileData* pBoneFileData = new BoneFileData();
	m_BoneFileDatas.AddElement(File,pBoneFileData);
	LuaPlus::LuaState*	pScript = ScriptHelper::CreateLuaState();
	// fix RAII bug
	{
		if (!ScriptHelper::DoFile(*pScript, File))
		{
			LuaPlus::LuaState::Destroy( pScript );
			UTIL_SAFE_DELETE(pBoneFileData);  			
		} 	
		
		LuaPlus::LuaObject BoneTable = pScript->GetGlobal("Bones");
		for(int i =0; i <BoneTable.GetTableCount(); i++)
		{
			LuaPlus::LuaObject Obj = BoneTable.GetByIndex(i+1);

			BoneData*	pBoneData = new BoneData();
			pBoneData->ID  = ScriptHelper::GetTableInt(Obj,"ID");
			pBoneData->Name = ScriptHelper::GetTableString(Obj,"Name"); 			
			pBoneFileData->m_BoneDatas.push_back(pBoneData);

		}
		//--------------------------
		LuaPlus::LuaObject AnimationTable = pScript->GetGlobal("Animation");
		for(int i =0; i <AnimationTable.GetTableCount(); i++)
		{
			AnimationData* pAnimationData = new AnimationData();
			pAnimationData->StepID = i + 1;
			pAnimationData->Duration = 0.5f;
			pBoneFileData->m_AnimationDatas.push_back(pAnimationData);
						
			LuaPlus::LuaObject Obj = AnimationTable.GetByIndex(i+1);
			//int StepID = ScriptHelper::GetTableInt(Obj,"StepID");
			LuaPlus::LuaObject ParTable = Obj.GetByName("Parts");
			

			for(int j =0; j <ParTable.GetTableCount(); j++)
			{
				AnimationPartData* pAnimationPartData = new AnimationPartData();
	

				LuaPlus::LuaObject PartObj = ParTable.GetByIndex(j+1);
				
				pAnimationPartData->ID = ScriptHelper::GetTableInt(PartObj,"ID");
				pAnimationPartData->Rotation =  ScriptHelper::GetTableFloat(PartObj,"Rotation");
				
				pAnimationPartData->CenterRelative = ScriptHelper::GetTableVec2(PartObj,"CenterRelative");
				float TempScale =  FIGConstants::TEXTURE_NATIVE_HEIGHT /(float)GetGraphics()->GetScreenHeight();
				TempScale *= ( (float)GetGraphics()->GetScreenWidth() / FIGConstants::TEXTURE_NATIVE_WIDTH);
				pAnimationPartData->CenterRelative.y *=  TempScale;

				

				pAnimationData->m_AnimationPartDatas.push_back(pAnimationPartData);

			}  
		}  

		//-------------------

		LuaPlus::LuaObject WPTable = pScript->GetGlobal("WayPoint");
		for(int i =0; i <WPTable.GetTableCount(); i++)
		{
			LuaPlus::LuaObject Obj = WPTable.GetByIndex(i+1);

			FIGBoneAnimation::WayPoint* pWP = new FIGBoneAnimation::WayPoint();
	
			pWP->m_ID = ScriptHelper::GetTableInt(Obj,"ID");
			pWP->m_Pos = ScriptHelper::GetTableVec2(Obj,"Pos");
 
			float TempScale =  FIGConstants::TEXTURE_NATIVE_HEIGHT /(float)GetGraphics()->GetScreenHeight();
			TempScale *= ( (float)GetGraphics()->GetScreenWidth() / FIGConstants::TEXTURE_NATIVE_WIDTH);
			pWP->m_Pos.y  *= TempScale;

			pBoneFileData->m_pWPs.push_back(pWP);
		}
	}

   LuaPlus::LuaState::Destroy( pScript );   
   
}

FIGBoneFileCache::BoneFileData*		FIGBoneFileCache::GetBoneFileDataByFileName(const std::string& Name)
{
	return m_BoneFileDatas.GetElement(Name);
}

